home *** CD-ROM | disk | FTP | other *** search
/ Komputer for Alle 2004 #2 / K-CD-2-2004.ISO / OpenOffice Sv / f_0397 / python-core-2.2.2 / lib / test / test_trace.py < prev    next >
Encoding:
Python Source  |  2003-07-18  |  5.9 KB  |  220 lines

  1. # Testing the line trace facility.
  2.  
  3. import test_support
  4. import unittest
  5. import sys
  6. import difflib
  7.  
  8. if not __debug__:
  9.     raise test_support.TestSkipped, "tracing not supported under -O"
  10.  
  11. # A very basic example.  If this fails, we're in deep trouble.
  12. def basic():
  13.     return 1
  14.  
  15. basic.events = [(0, 'call'),
  16.                 (0, 'line'),
  17.                 (1, 'line'),
  18.                 (1, 'return')]
  19.  
  20. # Armin Rigo's failing example:
  21. def arigo_example():
  22.     x = 1
  23.     del x
  24.     while 0:
  25.         pass
  26.     x = 1
  27.  
  28. arigo_example.events = [(0, 'call'),
  29.                         (0, 'line'),
  30.                         (1, 'line'),
  31.                         (2, 'line'),
  32.                         (3, 'line'),
  33.                         (3, 'line'),
  34.                         (5, 'line'),
  35.                         (5, 'return')]
  36.  
  37. # check that lines consisting of just one instruction get traced:
  38. def one_instr_line():
  39.     x = 1
  40.     del x
  41.     x = 1
  42.  
  43. one_instr_line.events = [(0, 'call'),
  44.                          (0, 'line'),
  45.                          (1, 'line'),
  46.                          (2, 'line'),
  47.                          (3, 'line'),
  48.                          (3, 'return')]
  49.  
  50. def no_pop_tops():      # 0
  51.     x = 1               # 1
  52.     for a in range(2):  # 2
  53.         if a:           # 3
  54.             x = 1       # 4
  55.         else:           # 5
  56.             x = 1       # 6
  57.  
  58. no_pop_tops.events = [(0, 'call'),
  59.                       (0, 'line'),
  60.                       (1, 'line'),
  61.                       (2, 'line'),
  62.                       (2, 'line'),
  63.                       (3, 'line'),
  64.                       (6, 'line'),
  65.                       (2, 'line'),
  66.                       (3, 'line'),
  67.                       (4, 'line'),
  68.                       (2, 'line'),
  69.                       (2, 'return')]
  70.  
  71. def no_pop_blocks():
  72.     while 0:
  73.         bla
  74.     x = 1
  75.  
  76. no_pop_blocks.events = [(0, 'call'),
  77.                         (0, 'line'),
  78.                         (1, 'line'),
  79.                         (1, 'line'),
  80.                         (3, 'line'),
  81.                         (3, 'return')]
  82.  
  83. def called(): # line -3
  84.     x = 1
  85.  
  86. def call():   # line 0
  87.     called()
  88.  
  89. call.events = [(0, 'call'),
  90.                (0, 'line'),
  91.                (1, 'line'),
  92.                (-3, 'call'),
  93.                (-3, 'line'),
  94.                (-2, 'line'),
  95.                (-2, 'return'),
  96.                (1, 'return')]
  97.  
  98. def raises():
  99.     raise Exception
  100.  
  101. def test_raise():
  102.     try:
  103.         raises()
  104.     except Exception, exc:
  105.         x = 1
  106.  
  107. test_raise.events = [(0, 'call'),
  108.                      (0, 'line'),
  109.                      (1, 'line'),
  110.                      (2, 'line'),
  111.                      (-3, 'call'),
  112.                      (-3, 'line'),
  113.                      (-2, 'line'),
  114.                      (-2, 'exception'),
  115.                      (2, 'exception'),
  116.                      (3, 'line'),
  117.                      (4, 'line'),
  118.                      (4, 'return')]
  119.  
  120. def _settrace_and_return(tracefunc):
  121.     sys.settrace(tracefunc)
  122.     sys._getframe().f_back.f_trace = tracefunc
  123. def settrace_and_return(tracefunc):
  124.     _settrace_and_return(tracefunc)
  125.  
  126. settrace_and_return.events = [(1, 'return')]
  127.  
  128. def _settrace_and_raise(tracefunc):
  129.     sys.settrace(tracefunc)
  130.     sys._getframe().f_back.f_trace = tracefunc
  131.     raise RuntimeError
  132. def settrace_and_raise(tracefunc):
  133.     try:
  134.         _settrace_and_raise(tracefunc)
  135.     except RuntimeError, exc:
  136.         pass
  137.  
  138. settrace_and_raise.events = [(2, 'exception'),
  139.                              (3, 'line'),
  140.                              (4, 'line'),
  141.                              (4, 'return')]
  142.  
  143. class Tracer:
  144.     def __init__(self):
  145.         self.events = []
  146.     def trace(self, frame, event, arg):
  147.         self.events.append((frame.f_lineno, event))
  148.         return self.trace
  149.  
  150. class TraceTestCase(unittest.TestCase):
  151.     def compare_events(self, line_offset, events, expected_events):
  152.         events = [(l - line_offset, e) for (l, e) in events]
  153.         if events != expected_events:
  154.             self.fail(
  155.                 "events did not match expectation:\n" +
  156.                 "\n".join(difflib.ndiff(map(str, expected_events),
  157.                                         map(str, events))))
  158.  
  159.  
  160.     def run_test(self, func):
  161.         tracer = Tracer()
  162.         sys.settrace(tracer.trace)
  163.         func()
  164.         sys.settrace(None)
  165.         self.compare_events(func.func_code.co_firstlineno,
  166.                             tracer.events, func.events)
  167.  
  168.     def run_test2(self, func):
  169.         tracer = Tracer()
  170.         func(tracer.trace)
  171.         sys.settrace(None)
  172.         self.compare_events(func.func_code.co_firstlineno,
  173.                             tracer.events, func.events)
  174.  
  175.     def test_1_basic(self):
  176.         self.run_test(basic)
  177.     def test_2_arigo(self):
  178.         self.run_test(arigo_example)
  179.     def test_3_one_instr(self):
  180.         self.run_test(one_instr_line)
  181.     def test_4_no_pop_blocks(self):
  182.         self.run_test(no_pop_blocks)
  183.     def test_5_no_pop_tops(self):
  184.         self.run_test(no_pop_tops)
  185.     def test_6_call(self):
  186.         self.run_test(call)
  187.     def test_7_raise(self):
  188.         self.run_test(test_raise)
  189.  
  190.     def test_8_settrace_and_return(self):
  191.         self.run_test2(settrace_and_return)
  192.     def test_9_settrace_and_raise(self):
  193.         self.run_test2(settrace_and_raise)
  194.  
  195. class RaisingTraceFuncTestCase(unittest.TestCase):
  196.     def test_it(self):
  197.         def tr(frame, event, arg):
  198.             raise ValueError # just something that isn't RuntimeError
  199.         def f():
  200.             return 1
  201.         try:
  202.             for i in xrange(sys.getrecursionlimit() + 1):
  203.                 sys.settrace(tr)
  204.                 try:
  205.                     f()
  206.                 except ValueError:
  207.                     pass
  208.                 else:
  209.                     self.fail("exception not thrown!")
  210.         except RuntimeError:
  211.             self.fail("recursion counter not reset")
  212.  
  213.  
  214. def test_main():
  215.     test_support.run_unittest(TraceTestCase)
  216.     test_support.run_unittest(RaisingTraceFuncTestCase)
  217.  
  218. if __name__ == "__main__":
  219.     test_main()
  220.